package com.example.demo.interceptor;

import cn.hutool.core.util.ObjectUtil;
import com.example.demo.config.DataSourceContextHolder;
import com.example.demo.constant.RedisConstant;
import com.example.demo.util.Redis2Service;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;

/**
 * fileName:DataSourceInterceptor
 * description: 自定义拦截器，拦截先前Nginx设置的租户信息，并设置到DataSourceTenantContextHolder中。
 * author: LJV
 * createTime:2022/4/2 15:05
 * version:1.0.0
 */
@Slf4j
@Component
public class DataSourceInterceptor implements HandlerInterceptor {

    @Autowired
    private Redis2Service redis2Service;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
            String tenantHeader = request.getHeader("tenant");
            if (StringUtils.hasText(tenantHeader)) {
                Subject subject = SecurityUtils.getSubject();
                //已登录
                if (ObjectUtil.isNotNull(subject) && ObjectUtil.isNotNull(subject.getPrincipal())) {
                    Serializable sessionId = subject.getSession().getId();
                    //用请求的租户信息替换掉当前sessionId的租户信息
                    StringBuffer stringBuffer = new StringBuffer(sessionId.toString());
                    StringBuffer replace = stringBuffer.replace(0, 3, tenantHeader);

                    String redisSessionId = RedisConstant.PREFIX + replace;
                    System.out.println("redisSessionId = " + redisSessionId);
                    boolean hasKey = redis2Service.hasKey(redisSessionId);
                    if (hasKey) {
                        DataSourceContextHolder.setDataSource(tenantHeader);
                    } else {
                        log.info("租户信息和登录用户不符，拒绝请求");
                        throw new RuntimeException("租户信息和登录用户不符，拒绝请求");
//                        return false;
                    }
                } else { //未登录
                    DataSourceContextHolder.setDataSource(tenantHeader);
                }
            } else {
                log.info("没有租户信息，使用默认数据源");
            }

        return true;
    }
}
